<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    table {
      table-layout: fixed;
      width: 100%;
      border-collapse: collapse;
    }

    th, td {
      border: 1px solid #999;
      padding: 10px;
    }

    h1 {
      text-align: center;
    }
  </style>
</head>
<body>
<table>
  <thead>
  <tr>
    <th>分公司</th>
    <th>NPS值</th>
    <th>分公司贬损者数量</th>
    <th>分公司总经理罚金</th>
    <th>分公司市场主管罚金</th>
    <th>分部</th>
    <th>分部贬损者数量</th>
    <th>分部经理罚金</th>
    <th>店铺</th>
    <th>店铺贬损者数量</th>
    <th>销售代表罚金</th>
    <th>合计罚金</th>
  </tr>
  </thead>
  <tbody class="tbody"></tbody>
</table>


<script>

  const shopList = [
    {
      "shopName": "xx店",
      "shopDetractorsNum": "1",
      "saleRepForfeit": "20"
    },
    {
      "shopName": "yy店",
      "shopDetractorsNum": "1",
      "saleRepForfeit": "20"
    },
    {
      "shopName": "zz店",
      "shopDetractorsNum": "1",
      "saleRepForfeit": "20"
    }
  ]
  const departments = [
    {
      "branchDepartment": "xx连锁管理部",
      "branchDepartmentDetractorsNum": "3",
      "branchDepartmentManagerForfeit": "150",
      "monthlyPunishmentShopModels": [
        {
          "shopName": "xx店1",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "yy店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "xx店3",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "yy店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "zz店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        }
      ]
    },
    {
      "branchDepartment": "yy连锁管理部",
      "branchDepartmentDetractorsNum": "2",
      "branchDepartmentManagerForfeit": "250",
      "monthlyPunishmentShopModels": [
        {
          "shopName": "xx店2",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "yy店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "yy店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "yy店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "yy店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        }
      ]
    },
    {
      "branchDepartment": "zz连锁管理部",
      "branchDepartmentDetractorsNum": "4",
      "branchDepartmentManagerForfeit": "350",
      "monthlyPunishmentShopModels": [
        {
          "shopName": "xx店3",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "yy店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        },
        {
          "shopName": "zz店",
          "shopDetractorsNum": "1",
          "saleRepForfeit": "20"
        }
      ]
    }
  ]
  const branchCompanies = [
    {
      "tableLocal": "0",
      "tableName": "月度惩罚金额",
      "branchCompany": "上海分公司",
      "npsValue": "73.85%",
      "branchCompanyDetractorsNum": "3",
      "branchCompanyManagerForfeit": "300",
      "branchCompanyMarketerForfeit": "90",
      "monthlyPunishmentDepartmentModels": [
        {
          "branchDepartment": "xx连锁管理部",
          "branchDepartmentDetractorsNum": "3",
          "branchDepartmentManagerForfeit": "150",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "yy连锁管理部",
          "branchDepartmentDetractorsNum": "2",
          "branchDepartmentManagerForfeit": "250",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "zz连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        }
      ],
      "totalForfeit": "600"
    },
    {
      "tableLocal": "0",
      "tableName": "月度惩罚金额",
      "branchCompany": "南京分公司",
      "npsValue": "62.50%",
      "branchCompanyDetractorsNum": "4",
      "branchCompanyManagerForfeit": "400",
      "branchCompanyMarketerForfeit": "120",
      "monthlyPunishmentDepartmentModels": [
        {
          "branchDepartment": "xx连锁管理部",
          "branchDepartmentDetractorsNum": "3",
          "branchDepartmentManagerForfeit": "150",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
          ]
        },
        {
          "branchDepartment": "yy连锁管理部",
          "branchDepartmentDetractorsNum": "2",
          "branchDepartmentManagerForfeit": "250",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
          ]
        },
        {
          "branchDepartment": "zz连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        }
      ],
      "totalForfeit": "800"
    },
    {
      "tableLocal": "0",
      "tableName": "月度惩罚金额",
      "branchCompany": "广州分公司",
      "npsValue": "55.88%",
      "branchCompanyDetractorsNum": "7",
      "branchCompanyManagerForfeit": "700",
      "branchCompanyMarketerForfeit": "210",
      "monthlyPunishmentDepartmentModels": [
        {
          "branchDepartment": "xx连锁管理部",
          "branchDepartmentDetractorsNum": "3",
          "branchDepartmentManagerForfeit": "150",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "yy连锁管理部",
          "branchDepartmentDetractorsNum": "2",
          "branchDepartmentManagerForfeit": "250",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "zz连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "xx店111",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店222",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "hh连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
      ],
      "totalForfeit": "1400"
    },
    {
      "tableLocal": "0",
      "tableName": "月度惩罚金额",
      "branchCompany": "贵阳分公司",
      "npsValue": "79.78%",
      "branchCompanyDetractorsNum": "1",
      "branchCompanyManagerForfeit": "100",
      "branchCompanyMarketerForfeit": "30",
      "monthlyPunishmentDepartmentModels": [
        {
          "branchDepartment": "xx连锁管理部",
          "branchDepartmentDetractorsNum": "3",
          "branchDepartmentManagerForfeit": "150",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "yy连锁管理部",
          "branchDepartmentDetractorsNum": "2",
          "branchDepartmentManagerForfeit": "250",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "zz连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        }
      ],
      "totalForfeit": "200"
    },
    {
      "tableLocal": "0",
      "tableName": "月度惩罚金额",
      "branchCompany": "上海分公司",
      "npsValue": "73.85%",
      "branchCompanyDetractorsNum": "3",
      "branchCompanyManagerForfeit": "300",
      "branchCompanyMarketerForfeit": "90",
      "monthlyPunishmentDepartmentModels": [
        {
          "branchDepartment": "xx连锁管理部",
          "branchDepartmentDetractorsNum": "3",
          "branchDepartmentManagerForfeit": "150",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "yy连锁管理部",
          "branchDepartmentDetractorsNum": "2",
          "branchDepartmentManagerForfeit": "250",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "zz连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        }
      ],
      "totalForfeit": "600"
    },
    {
      "tableLocal": "0",
      "tableName": "月度惩罚金额",
      "branchCompany": "南京分公司",
      "npsValue": "62.50%",
      "branchCompanyDetractorsNum": "4",
      "branchCompanyManagerForfeit": "400",
      "branchCompanyMarketerForfeit": "120",
      "monthlyPunishmentDepartmentModels": [
        {
          "branchDepartment": "xx连锁管理部",
          "branchDepartmentDetractorsNum": "3",
          "branchDepartmentManagerForfeit": "150",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "yy连锁管理部",
          "branchDepartmentDetractorsNum": "2",
          "branchDepartmentManagerForfeit": "250",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "zz连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        }
      ],
      "totalForfeit": "800"
    },
    {
      "tableLocal": "0",
      "tableName": "月度惩罚金额",
      "branchCompany": "广州分公司",
      "npsValue": "55.88%",
      "branchCompanyDetractorsNum": "7",
      "branchCompanyManagerForfeit": "700",
      "branchCompanyMarketerForfeit": "210",
      "monthlyPunishmentDepartmentModels": [
        {
          "branchDepartment": "xx连锁管理部",
          "branchDepartmentDetractorsNum": "3",
          "branchDepartmentManagerForfeit": "150",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "yy连锁管理部",
          "branchDepartmentDetractorsNum": "2",
          "branchDepartmentManagerForfeit": "250",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "zz连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        }
      ],
      "totalForfeit": "1400"
    },
    {
      "tableLocal": "0",
      "tableName": "月度惩罚金额",
      "branchCompany": "贵阳分公司",
      "npsValue": "79.78%",
      "branchCompanyDetractorsNum": "1",
      "branchCompanyManagerForfeit": "100",
      "branchCompanyMarketerForfeit": "30",
      "monthlyPunishmentDepartmentModels": [
        {
          "branchDepartment": "xx连锁管理部",
          "branchDepartmentDetractorsNum": "3",
          "branchDepartmentManagerForfeit": "150",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "yy连锁管理部",
          "branchDepartmentDetractorsNum": "2",
          "branchDepartmentManagerForfeit": "250",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        },
        {
          "branchDepartment": "zz连锁管理部",
          "branchDepartmentDetractorsNum": "4",
          "branchDepartmentManagerForfeit": "350",
          "monthlyPunishmentShopModels": [
            {
              "shopName": "xx店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "yy店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            },
            {
              "shopName": "zz店",
              "shopDetractorsNum": "1",
              "saleRepForfeit": "20"
            }
          ]
        }
      ],
      "totalForfeit": "200"
    }
  ]

  const rows = createTable(branchCompanies)
  const tbody = document.querySelector('.tbody')
  tbody.innerHTML = rows

  function createTable(data) {
    const fields = [
      'branchCompany',
      'npsValue',
      'branchCompanyDetractorsNum',
      'branchCompanyManagerForfeit',
      'branchCompanyMarketerForfeit',
      'monthlyPunishmentDepartmentModels',
      'totalForfeit'
    ]
    const result = data.map(item => {
      const departments = item.monthlyPunishmentDepartmentModels || []
      const shopsNumList = departments.map(department => (department.monthlyPunishmentShopModels || []).length)
      const rowspan = shopsNumList.reduce((acc, item) => acc + item, 0)
      let departmentRows = createDepartment(departments)
      const columns = fields.map(field => {
        if(field === 'monthlyPunishmentDepartmentModels') {
          return departmentRows.shift()
        }
        return `<td rowspan="${rowspan}">${item[field]}</td>`
      }).join('')
      const row = `<tr>${columns}</tr>` + departmentRows.join('')
      return row
    })
    return result.join('')
  }

  function createDepartment(data) {
    const fields = [
      'branchDepartment',
      'branchDepartmentDetractorsNum',
      'branchDepartmentManagerForfeit'
    ]
    let firstRow = []
    const rows = data.map((item, index) => {
      const shops = item.monthlyPunishmentShopModels || [];
      const rowspan = shops.length;
      let shopRows = createShop(shops)
      const columns = fields.map(field => `<td rowspan="${rowspan}">${item[field]}</td>`).join('') + shopRows.shift()
      if (index === 0) {
        firstRow = shopRows
        return columns
      }
      return `<tr>${columns}</tr>` + shopRows.join('')
    })
    const result = [rows.shift()].concat(firstRow.concat(rows).join(''))
    return result
  }

  function createShop(data) {
    const fields = ['shopName', 'shopDetractorsNum', 'saleRepForfeit']
    let rows = data.map((item, index) => {
      const columns = fields.map(field => `<td>${item[field]}</td>`).join('')
      return index === 0 ? columns : `<tr>${columns}</tr>`
    });
    const result = [rows.shift()].concat(rows.join(''))
    return result
  }
</script>
</body>
</html>
